package com.deng.eventflow.core.functions;

import com.deng.eventflow.core.Context;
import com.deng.eventflow.core.EventTracker;

import java.util.Set;

public class Constant extends Function {
    /**
     * A constant representing the number zero
     */
    public static final transient Constant ZERO = new Constant(0);

    /**
     * A constant representing the number one
     */
    public static final transient Constant ONE = new Constant(1);

    /**
     * The value to return by this constant
     */
    private final Object m_value;

    /**
     * Creates a new constant
     *
     * @param value
     *          The value associated to this constant
     */
    public Constant(Object value)
    {
        super();
        m_value = value;
    }

    @Override
    public void evaluate(Object[] inputs, Object[] outputs, Context context, EventTracker tracker)
    {
        outputs[0] = m_value;
        if (tracker != null)
        {
            tracker.associateToOutput(-1, 0, 0, 0, 0);
        }
    }

    @Override
    public void evaluate(Object[] inputs, Object[] outputs)
    {
        evaluate(inputs, outputs, null);
    }

    @Override
    public boolean evaluatePartial(Object[] inputs, Object[] outputs, Context context)
    {
        outputs[0] = m_value;
        return true;
    }

    @Override
    public int getInputArity()
    {
        return 0;
    }

    @Override
    public int getOutputArity()
    {
        return 1;
    }

    @Override
    public void reset()
    {
        // Nothing to do
    }

    @Override
    public Constant duplicate(boolean with_state)
    {
        return new Constant(m_value);
    }

    @Override
    public void getInputTypesFor(Set<Class<?>> classes, int index)
    {
        // Nothing to do
        return;
    }

    @Override
    public Class<?> getOutputTypeFor(int index)
    {
        return m_value.getClass();
    }

    @Override
    public String toString()
    {
        if (m_value == null)
        {
            return "null";
        }
        return m_value.toString();
    }

    /**
     * Gets the actual object that this constant processor returns
     *
     * @return The value
     */
    public Object getValue()
    {
        return m_value;
    }

    /**
     * @since 0.10.2
     */
    @Override
    public Object printState()
    {
        return m_value;
    }

    /**
     * @since 0.10.2
     */
    @Override
    public Constant readState(Object o)
    {
        return new Constant(o);
    }
}
